/*
 * zyFile.js 基于HTML5 文件上传的核心脚本 http://www.czlqibu.com
 * by zhangyan 2014-06-21   QQ : 623585268
*/
var ZYFILE = {
	    rootElem : null,              // 根对象
		fileInput : null,             // 选择文件按钮dom对象
		uploadInput : null,           // 上传文件按钮dom对象
		dragDrop: null,				  //  拖拽敏感区域
		url : "",  					  // 上传action路径
		removeUrl        : null,  	  // 删除文件的路径
		selectFile : [],  			  // 新上传的文件数组
		uploadFile : [],  			  // 需要上传的文件数组
		allUploadFile : [],           // 存放永久的文件数组，方便删除使用
		fileIndex : 0,                // 下一次添加需要在它的基础上添加索引
        fileTotal : 0,                  // 代表文件总个数
		/* 提供给外部的接口 */
		filterFile : function(files){ // 提供给外部的过滤文件格式等的接口，外部需要把过滤后的文件返回
			return files;
		},
		onSelect : function(selectFile, files){      // 提供给外部获取选中的文件，供外部实现预览等功能  selectFile:当前选中的文件  allFiles:还没上传的全部文件
			
		},
		onDelete : function(file, files){            // 提供给外部获取删除的单个文件，供外部实现删除效果  file:当前删除的文件  files:删除之后的文件
			
		},
		onProgress : function(file, loaded, total){  // 提供给外部获取单个文件的上传进度，供外部实现上传进度效果
			
		},
		onSuccess : function(file, responseInfo){    // 提供给外部获取单个文件上传成功，供外部实现成功效果
			
		},
		onFailure : function(file, responseInfo){    // 提供给外部获取单个文件上传失败，供外部实现失败效果
		
		},
		onComplete : function(responseInfo){         // 提供给外部获取全部文件上传完成，供外部实现完成效果
			
		},
		
		/* 内部实现功能方法 */
		// 获得选中的文件
		//文件拖放
		funDragHover: function(e) {
			e.stopPropagation();
			e.preventDefault();
			this[e.type === "dragover"? "onDragOver": "onDragLeave"].call(e.target);
			return this;
		},
		// 获取文件
		funGetFiles : function(e){  
			var self = this;
			// 取消鼠标经过样式
			this.funDragHover(e);
			// 从事件中获取选中的所有文件
			var selfiles = e.target.files || e.dataTransfer.files;
			// 过滤无效文件
			var selfiles=this.filterFile(selfiles);
			if(selfiles.length==0){
				return;
			}
			//将上次上传文件与今次合并
			var tmpFiles = [];
			// 因为jquery的inArray方法无法对object数组进行判断是否存在于，所以只能提取名称进行判断
			var aArr = [];  // 之前文件的名称数组
			var sArr = [];  // 现在文件的名称数组
			$.each(self.allUploadFile, function(k, v){
				if(!v.isDel){
					aArr.push(v.name);
				}
			});
			$.each(selfiles, function(k, v){
				sArr.push(v.name);
			});
			
			$.each(sArr, function(k, v){
				// 获得当前选择的每一个文件   判断当前这一个文件是否存在于之前的文件当中
				if($.inArray(v, aArr) < 0){  // 不存在
					selfiles[k].isDel=false;
					tmpFiles.push(selfiles[k]);
				}
			});
			
			// 如果tmpFiles进行过过滤上一次选择的文件的操作，需要把过滤后的文件赋值
			this.selectFile = tmpFiles;
			// 调用对文件处理的方法
			this.funDealtFiles();
			return true;
		},
		// 处理过滤后的文件，给每个文件设置下标
		funDealtFiles : function(){
			var self = this;
			// 目前是遍历所有的文件，给每个文件增加唯一索引值
			$.each(this.selectFile, function(k, v){
				// 因为涉及到继续添加，所以下一次添加需要在总个数的基础上添加
				v.index = self.fileIndex;
				// 添加一个之后自增
				self.fileIndex++;
				self.fileTotal++;
			});
			// 先把当前选中的文件保存备份 
			// 合并下上传的文件
			this.uploadFile = this.uploadFile.concat(this.selectFile);
			// 要把全部的文件都保存下来，因为删除所使用的下标是全局的变量
			this.allUploadFile = this.allUploadFile.concat(this.selectFile);
			
			// 执行选择回调
			this.onSelect(this.selectFile, this.uploadFile);
			console.info("继续选择");
			console.info(this.uploadFile);
			return this;
		},
		// 处理需要删除的文件  isCb代表是否回调onDelete方法  
		// 因为上传完成并不希望在页面上删除div，但是单独点击删除的时候需要删除div   所以用isCb做判断
		funDeleteFile : function(delFileIndex){
			var self = this;  // 在each中this指向没个v  所以先将this保留
			// 合并下上传的文件
			var delFile = this.allUploadFile[delFileIndex];
			// 回调删除方法，供外部进行删除效果的实现
			if(delFile.fileId){
				if(self.removeUrl){
					$.get(self.removeUrl+delFile.fileId,function(data,status){
				        console.info("数据: " + data + "\n状态: " + status);
				        if(status=="success"){
				        	//清除上传列表
							this.uploadFile=funDeleteFileFormArray(delFile,this.uploadFile,true);
							//清除所有列表
							this.allUploadFile=funDeleteFileFormArray(delFile,this.allUploadFile,false);
							//文件总数量减 1
							self.fileTotal--;
				        	self.onDelete(delFile, this.uploadFile);
				        }
				    });
				}else{
					//清除上传列表
					this.uploadFile=funDeleteFileFormArray(delFile,this.uploadFile,true);
					//清除所有列表
					this.allUploadFile=funDeleteFileFormArray(delFile,this.allUploadFile,false);
					//文件总数量减 1
					self.fileTotal--;
					self.onDelete(delFile, this.uploadFile);
				}
			}else{
				//清除上传列表
				this.uploadFile=funDeleteFileFormArray(delFile,this.uploadFile,true);
				//清除所有列表
				this.allUploadFile=funDeleteFileFormArray(delFile,this.allUploadFile,false);
				//文件总数量减 1
				self.fileTotal--;
				self.onDelete(delFile, this.uploadFile);
			}
			console.info("还剩这些文件没有上传:");
			console.info(this.uploadFile);
			return true;
		},
		// 上传多个文件
		funUploadFiles : function(){
			var self = this;  // 在each中this指向没个v  所以先将this保留
			// 遍历所有文件  ，在调用单个文件上传的方法
			$.each(this.uploadFile, function(k, v){
				self.funUploadFile(v);
			});
		},
		// 上传单个个文件
		funUploadFile : function(file){
			var self = this;  // 在each中this指向没个v  所以先将this保留
			var formdata = new FormData();
			formdata.append("fileList", file);
			// 发起jquery的ajax请求
			$.ajax({
				method:'POST',
				url:self.url,
				data:formdata,
				contentType:false,
				processData:false,
				success: function(data) {
					self.uploadFile=funDeleteFileFormArray(file,self.uploadFile,true);
					self.onSuccess(file,data);
				},
				error:function(xhr,status,error){
					self.onFailure(file);
				}
			});
		},
		// 返回需要上传的文件
		funReturnNeedFiles : function(){
			return this.uploadFile;
		},
		
		// 初始化
		init : function(){  // 初始化方法，在此给选择、上传按钮绑定事件
			var self = this;  // 克隆一个自身
			console.info($(self).parents(".domo").attr("id"));
			if (this.dragDrop) {
				this.dragDrop.addEventListener("dragover", function(e) { self.funDragHover(e); }, false);
				this.dragDrop.addEventListener("dragleave", function(e) { self.funDragHover(e); }, false);
				this.dragDrop.addEventListener("drop", function(e) { self.funGetFiles(e); }, false);
			}
			
			// 如果选择按钮存在
			if(self.fileInput){
				// 绑定change事件
				this.fileInput.addEventListener("change", function(e) {
					self.funGetFiles(e); 
					$(this).val("");
				}, false);	
			}
			
			// 如果上传按钮存在
			if(self.uploadInput){
				// 绑定click事件
				this.uploadInput.addEventListener("click", function(e) {
					self.funUploadFiles(e); 
				}, false);	
			}
		}
};


function funDeleteFileFormArray(file,fileArray,isDelete){
	var tmpFile = [];  // 用来替换的文件数组
	// 目前是遍历所有的文件，对比每个文件  删除
	if(fileArray){
		$.each(fileArray, function(k, v){
			if(file != v){
				// 如果不是删除的那个文件 就放到临时数组中
				tmpFile.push(v);
			}else{
				if(!isDelete){
					v.isDel=true;
					tmpFile.push(v);
				}
			}
		});
	}
	return tmpFile;
}

 /* www.jq22.com */













